package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"mcp-server/internal/config"
	"mcp-server/internal/health"
	"mcp-server/internal/qdrant"
	"mcp-server/internal/vector"
)

// 版本信息（构建时注入）
var (
	Version   = "dev"
	BuildTime = "unknown"
)

func main() {
	// 命令行参数
	var (
		port       = flag.Int("port", 0, "HTTP服务端口（优先级最高）")
		端口         = flag.Int("端口", 0, "HTTP服务端口（中文命令）")
		vecPath    = flag.String("vec-path", "", "自定义向量库路径")
		kbPath     = flag.String("kb-path", "", "知识库路径")
		configPath = flag.String("config", "config.yaml", "配置文件路径")
		help       = flag.Bool("help", false, "显示帮助信息")
		帮助         = flag.Bool("帮助", false, "显示帮助信息（中文命令）")
		version    = flag.Bool("version", false, "显示版本信息")

		// 端口管理命令
		checkPort = flag.Bool("check-port", false, "检查端口状态")
		检查端口      = flag.Bool("检查端口", false, "检查端口状态（中文命令）")

		// 向量库管理命令
		updateVec      = flag.Bool("update-vec", false, "更新向量库")
		更新向量库          = flag.Bool("更新向量库", false, "更新向量库（中文命令）")
		fullUpdateVec  = flag.Bool("full-update-vec", false, "全量更新向量库")
		checkVecStatus = flag.Bool("check-vec-status", false, "查看向量库状态")
		查看向量库状态        = flag.Bool("查看向量库状态", false, "查看向量库状态（中文命令）")
		backupVec      = flag.Bool("backup-vec", false, "备份向量库")
		restoreVec     = flag.Bool("restore-vec", false, "恢复向量库")

		// 启动状态校验命令
		bootstrap     = flag.Bool("bootstrap", false, "运行启动状态校验")
		启动校验          = flag.Bool("启动校验", false, "运行启动状态校验（中文命令）")
		skipBootstrap = flag.Bool("skip-bootstrap", false, "跳过启动状态校验")
		跳过启动校验        = flag.Bool("跳过启动校验", false, "跳过启动状态校验（中文命令）")
	)

	flag.Parse()

	// 处理中文命令参数
	if *帮助 {
		*help = true
	}
	if *端口 > 0 {
		*port = *端口
	}
	if *检查端口 {
		*checkPort = true
	}
	if *更新向量库 {
		*updateVec = true
	}
	if *查看向量库状态 {
		*checkVecStatus = true
	}
	if *启动校验 {
		*bootstrap = true
	}
	if *跳过启动校验 {
		*skipBootstrap = true
	}

	// 显示版本信息
	if *version {
		fmt.Printf("MCP Server %s (构建时间: %s)\n", Version, BuildTime)
		return
	}

	// 显示帮助信息
	if *help {
		printHelp()
		return
	}

	// 初始化配置管理器
	configManager := config.NewConfigManager(*configPath)
	if err := configManager.LoadConfig(); err != nil {
		log.Fatalf("配置加载失败: %v", err)
	}

	// 处理启动状态校验命令
	if *bootstrap {
		handleBootstrap(configManager, *configPath)
		return
	}

	// 处理端口检查命令
	if *checkPort {
		handleCheckPort(configManager, *port)
		return
	}

	// 处理向量库管理命令
	if *checkVecStatus {
		handleCheckVecStatus(*configPath, *vecPath, *kbPath)
		return
	}

	if *updateVec {
		handleUpdateVec(*configPath, *vecPath, *kbPath, false)
		return
	}

	if *fullUpdateVec {
		handleUpdateVec(*configPath, *vecPath, *kbPath, true)
		return
	}

	if *backupVec {
		handleBackupVec(*configPath, *vecPath, *kbPath)
		return
	}

	if *restoreVec {
		handleRestoreVec(*configPath, *vecPath, *kbPath)
		return
	}

	// 启动主服务
	if err := startServer(configManager, *port, *vecPath, *kbPath, *skipBootstrap); err != nil {
		log.Fatalf("服务启动失败: %v", err)
	}
}

func startServer(configManager *config.ConfigManager, cmdPort int, vecPath, kbPath string, skipBootstrap bool) error {
	log.Println("正在启动MCP服务器...")

	// 运行启动状态校验（除非跳过）
	if !skipBootstrap {
		log.Println("开始启动状态校验...")
		bootstrapChecker := health.NewBootstrapChecker(configManager.GetConfigPath(), ".")
		bootstrapStatus := bootstrapChecker.RunBootstrapChecks()

		// 打印校验摘要
		bootstrapChecker.PrintBootstrapSummary(bootstrapStatus)

		// 保存校验报告
		if err := bootstrapChecker.SaveBootstrapReport(bootstrapStatus, "logs/bootstrap-report.json"); err != nil {
			log.Printf("[WARNING] 保存启动报告失败: %v", err)
		}

		// 检查是否可以启动
		if !bootstrapStatus.ReadyToStart {
			return fmt.Errorf("启动状态校验失败，服务无法启动。请查看上述错误信息并修复问题")
		}

		// 如果端口被自动解析，使用新端口
		if bootstrapStatus.PortCheck.AutoResolved {
			cmdPort = bootstrapStatus.PortCheck.FinalPort
			log.Printf("[INFO] 使用自动解析的端口: %d", cmdPort)
		}
	}

	// 解析端口配置
	httpConfig := configManager.GetHTTPConfig()
	portConfig := &config.PortConfig{
		Port:         httpConfig.Port,
		Host:         httpConfig.Host,
		AutoScan:     httpConfig.AutoScan,
		ScanRange:    httpConfig.ScanRange,
		CheckTimeout: httpConfig.CheckTimeout,
	}

	portManager := config.NewPortManager(portConfig)
	finalPort, err := portManager.ResolvePort(cmdPort, httpConfig.Port)
	if err != nil {
		return fmt.Errorf("端口配置失败: %w", err)
	}

	// 如果端口发生变化，更新配置文件
	if finalPort != httpConfig.Port {
		fmt.Printf("[INFO] 更新配置文件中的端口: %d -> %d\n", httpConfig.Port, finalPort)
		if err := configManager.UpdateHTTPPort(finalPort); err != nil {
			log.Printf("[WARNING] 更新配置文件失败: %v", err)
		}
	}

	// 初始化Qdrant服务
	qdrantService, err := qdrant.InitializeQdrant(configManager.GetConfigPath(), vecPath, kbPath)
	if err != nil {
		return fmt.Errorf("Qdrant初始化失败: %w", err)
	}

	// 初始化向量化服务
	vectorIntegration := vector.NewVectorIntegration(qdrantService, configManager.GetConfig())
	if err := vectorIntegration.Initialize(); err != nil {
		return fmt.Errorf("向量化服务初始化失败: %w", err)
	}

	// 设置优雅关闭
	setupGracefulShutdown(qdrantService, vectorIntegration)

	// 启动HTTP服务
	log.Printf("MCP服务器已启动，监听端口: %d", finalPort)
	log.Printf("访问地址: http://%s:%d", httpConfig.Host, finalPort)
	log.Println("按 Ctrl+C 停止服务")

	// 保持服务运行
	select {}
}

func setupGracefulShutdown(qdrantService *qdrant.QdrantService, vectorIntegration *vector.VectorIntegration) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)

	go func() {
		<-c
		log.Println("收到关闭信号，正在优雅关闭...")

		if err := vectorIntegration.Close(); err != nil {
			log.Printf("关闭向量化服务时出错: %v", err)
		}

		if err := qdrantService.Close(); err != nil {
			log.Printf("关闭Qdrant服务时出错: %v", err)
		}

		log.Println("服务已关闭")
		os.Exit(0)
	}()
}

func handleBootstrap(configManager *config.ConfigManager, configPath string) {
	fmt.Println("=== 启动状态校验 ===")

	// 创建启动校验器
	bootstrapChecker := health.NewBootstrapChecker(configPath, ".")

	// 运行启动校验
	bootstrapStatus := bootstrapChecker.RunBootstrapChecks()

	// 打印校验摘要
	bootstrapChecker.PrintBootstrapSummary(bootstrapStatus)

	// 保存校验报告
	if err := bootstrapChecker.SaveBootstrapReport(bootstrapStatus, "logs/bootstrap-report.json"); err != nil {
		log.Printf("[WARNING] 保存启动报告失败: %v", err)
	}

	// 显示结果
	if bootstrapStatus.ReadyToStart {
		fmt.Println("\n✅ 启动状态校验通过，系统可以正常启动")
		if bootstrapStatus.PortCheck.AutoResolved {
			fmt.Printf("📍 建议使用端口: %d\n", bootstrapStatus.PortCheck.FinalPort)
		}
	} else {
		fmt.Println("\n❌ 启动状态校验失败，请修复上述问题后重试")
		os.Exit(1)
	}
}

func handleCheckPort(configManager *config.ConfigManager, cmdPort int) {
	fmt.Println("=== 端口状态检查 ===")

	httpConfig := configManager.GetHTTPConfig()
	portConfig := &config.PortConfig{
		Port:         httpConfig.Port,
		Host:         httpConfig.Host,
		AutoScan:     httpConfig.AutoScan,
		ScanRange:    httpConfig.ScanRange,
		CheckTimeout: httpConfig.CheckTimeout,
	}

	portManager := config.NewPortManager(portConfig)

	// 确定要检查的端口
	targetPort := cmdPort
	if targetPort == 0 {
		targetPort = httpConfig.Port
	}

	fmt.Printf("检查端口: %d\n", targetPort)
	fmt.Printf("主机地址: %s\n", httpConfig.Host)

	// 获取端口状态
	status := portManager.GetPortStatus(targetPort)

	fmt.Printf("端口状态: ")
	if status["available"].(bool) {
		fmt.Println("✅ 可用")
	} else {
		fmt.Println("❌ 被占用")
		if occupyingProcess, ok := status["occupying_process"]; ok {
			fmt.Printf("占用信息: %s\n", occupyingProcess)
		}
	}

	fmt.Printf("检查时间: %s\n", status["timestamp"])

	// 如果端口被占用且启用自动扫描，显示可用端口建议
	if !status["available"].(bool) && httpConfig.AutoScan {
		fmt.Println("\n正在扫描可用端口...")
		if availablePort, err := portManager.ResolvePort(0, targetPort); err == nil {
			fmt.Printf("建议使用端口: %d\n", availablePort)
		}
	}
}

func handleCheckVecStatus(configPath, vecPath, kbPath string) {
	log.Println("正在检查向量库状态...")

	qdrantService, err := qdrant.InitializeQdrant(configPath, vecPath, kbPath)
	if err != nil {
		log.Fatalf("初始化失败: %v", err)
	}
	defer qdrantService.Close()

	status := qdrantService.GetServiceStatus()

	fmt.Println("=== 向量库状态 ===")
	fmt.Printf("初始化状态: %v\n", status["initialized"])
	fmt.Printf("数据路径: %s\n", status["data_path"])

	if processID, ok := status["process_id"]; ok {
		fmt.Printf("进程ID: %v\n", processID)
	}

	if running, ok := status["process_running"]; ok {
		fmt.Printf("进程运行: %v\n", running)
	}

	if collectionInfo, ok := status["collection_info"]; ok {
		if info, ok := collectionInfo.(*qdrant.CollectionInfo); ok {
			fmt.Printf("集合名称: %s\n", info.Name)
			fmt.Printf("向量数量: %d\n", info.VectorCount)
			fmt.Printf("集合状态: %s\n", info.Status)
		}
	}
}

func handleUpdateVec(configPath, vecPath, kbPath string, fullUpdate bool) {
	updateType := "增量"
	if fullUpdate {
		updateType = "全量"
	}

	log.Printf("正在执行%s向量库更新...", updateType)

	// 加载配置
	configManager := config.NewConfigManager(configPath)
	if err := configManager.LoadConfig(); err != nil {
		log.Fatalf("配置加载失败: %v", err)
	}

	// 初始化Qdrant服务
	qdrantService, err := qdrant.InitializeQdrant(configPath, vecPath, kbPath)
	if err != nil {
		log.Fatalf("Qdrant初始化失败: %v", err)
	}
	defer qdrantService.Close()

	// 初始化向量化服务
	vectorIntegration := vector.NewVectorIntegration(qdrantService, configManager.GetConfig())
	if err := vectorIntegration.Initialize(); err != nil {
		log.Fatalf("向量化服务初始化失败: %v", err)
	}
	defer vectorIntegration.Close()

	// 确定知识库路径
	if kbPath == "" {
		docConfig := configManager.GetDocumentConfig()
		if docConfig.KnowledgeBasePath != "" {
			kbPath = docConfig.KnowledgeBasePath
		} else {
			log.Fatal("未指定知识库路径，请使用 -kb-path 参数或在配置文件中设置")
		}
	}

	// 执行向量库更新
	result, err := vectorIntegration.ProcessKnowledgeBase(kbPath, fullUpdate)
	if err != nil {
		log.Fatalf("向量库更新失败: %v", err)
	}

	// 显示更新结果
	fmt.Printf("=== %s向量库更新完成 ===\n", updateType)
	fmt.Printf("总文件数: %d\n", result.TotalFiles)
	fmt.Printf("处理成功: %d\n", result.SuccessFiles)
	fmt.Printf("处理失败: %d\n", result.FailedFiles)
	fmt.Printf("总分片数: %d\n", result.TotalChunks)
	fmt.Printf("向量化成功: %d\n", result.VectorizedChunks)
	fmt.Printf("处理时间: %d ms\n", result.ProcessTime)

	if len(result.Errors) > 0 {
		fmt.Println("\n错误信息:")
		for _, err := range result.Errors {
			fmt.Printf("- %s\n", err)
		}
	}

	if result.Statistics != nil {
		fmt.Println("\n统计信息:")
		for k, v := range result.Statistics {
			fmt.Printf("- %s: %v\n", k, v)
		}
	}
}

func handleBackupVec(configPath, vecPath, kbPath string) {
	log.Println("正在备份向量库...")

	// TODO: 实现向量库备份逻辑
	log.Println("向量库备份完成")
}

func handleRestoreVec(configPath, vecPath, kbPath string) {
	log.Println("正在恢复向量库...")

	// TODO: 实现向量库恢复逻辑
	log.Println("向量库恢复完成")
}

func printHelp() {
	fmt.Println("MCP服务器 - 基于向量数据库的本地知识库服务")
	fmt.Printf("版本: %s (构建时间: %s)\n", Version, BuildTime)
	fmt.Println()
	fmt.Println("用法:")
	fmt.Println("  mcp-server [选项]")
	fmt.Println()
	fmt.Println("服务选项:")
	fmt.Println("  -port int        HTTP服务端口（优先级最高）")
	fmt.Println("  -端口 int        HTTP服务端口（中文命令）")
	fmt.Println("  -config string   配置文件路径 (默认: config.yaml)")
	fmt.Println("  -kb-path string  知识库路径")
	fmt.Println("  -vec-path string 自定义向量库路径")
	fmt.Println()
	fmt.Println("端口管理:")
	fmt.Println("  -check-port      检查端口状态")
	fmt.Println("  -检查端口        检查端口状态（中文命令）")
	fmt.Println()
	fmt.Println("向量库管理:")
	fmt.Println("  -check-vec-status    查看向量库状态")
	fmt.Println("  -查看向量库状态      查看向量库状态（中文命令）")
	fmt.Println("  -update-vec          增量更新向量库")
	fmt.Println("  -更新向量库          增量更新向量库（中文命令）")
	fmt.Println("  -full-update-vec     全量更新向量库")
	fmt.Println("  -backup-vec          备份向量库")
	fmt.Println("  -restore-vec         恢复向量库")
	fmt.Println()
	fmt.Println("其他:")
	fmt.Println("  -help               显示此帮助信息")
	fmt.Println("  -帮助               显示此帮助信息（中文命令）")
	fmt.Println("  -version            显示版本信息")
	fmt.Println()
	fmt.Println("端口配置优先级:")
	fmt.Println("  1. 命令行参数 (-port)")
	fmt.Println("  2. 配置文件 (config.yaml)")
	fmt.Println("  3. 默认端口 (8765)")
	fmt.Println()
	fmt.Println("端口冲突处理:")
	fmt.Println("  - 自动扫描可用端口 (8766-8775)")
	fmt.Println("  - 显示占用进程信息")
	fmt.Println("  - 权限提示 (端口 < 1024)")
	fmt.Println()
	fmt.Println("示例:")
	fmt.Println("  mcp-server                           # 使用默认配置启动服务")
	fmt.Println("  mcp-server -port 8080                # 指定端口启动")
	fmt.Println("  mcp-server -端口 8080                # 中文命令指定端口")
	fmt.Println("  mcp-server -check-port               # 检查默认端口状态")
	fmt.Println("  mcp-server -check-port -port 8080    # 检查指定端口状态")
	fmt.Println("  mcp-server -vec-path /custom/path    # 自定义向量库路径")
	fmt.Println("  mcp-server -check-vec-status         # 检查向量库状态")
}
